Introduction

As the owner of a new bakery, Brandy Britches has decided that she needs an internet presence to supplement her local business. Ms. Britches approached a reputable firm, Gluvna Enterprises, about building her new website. After meeting with the developers, they decided to move forward with the new website using a phased approached and deliver the site to Ms. Britches in two sets of deliverables. The first deliverable will be a basic static website with a product menu, pictures of those products and contact information. At this time, online-ordering will not be available because Ms. Britches wishes to spend some additional time on researching shipping options. The second set of deliverables will include a fully functioning interactive website that offers online ordering and payment options. This project will focus on the design and development of the first set of deliverables.We will also cover the design of the database to be used as the data source of this website.

Site Development

CSS

The first thing the design team decided was on a color scheme and what types of fonts would be used for the site. The team used “cascading style sheets” (CSS) to accomplish uniform look and feel for the entire website and ensure continuity. CSS is a document format which provides a set of style rules which can then be incorporated in an XHTML or HTML document. It is a means to separate web content from formatting and presentation information. The following code is a demonstration of some of the code the CSS file used for the site:
CSSCode0.JPG
The we are using some basic tags to control minor things like the font used on the pages and background color. Now, we say minor, but when you start building websites with hundreds or even just dozens of pages, using the CSS stylesheet to control these options make the job of maintenance much easier. Below is an example of a basic page using the above style sheet:
MainCss0.JPG
To demonstrate how much easier using stylesheets makes maintenance and changes, Ms. Britches has decided that she does not like the font "Times New Roman", instead she likes "Arial". So the development team has the daunting task of changing font for all the pages they have developed up to this point. Mr. Gluvna decides that he will take over the task rather than ask his team, so he makes the change to the style sheet:
CSSCode1.JPG
Notice that the only thing that has changed is the font-family in the "body" and "p" tags. This small change will propagate throughout all pages that use the style sheet. The new version of the previous page we e​xamined is now this:
MainCss1.JPG

Also, in order to use the style sheets you must have the following code in all of your pages:

<link href="Styles.css" rel="stylesheet" type="text/css" />

Web Form Controls

Next, the team started building a page that would act as the template for the rest of the site. By using a template the team can further ensure continuity throughout the whole site. While building the template, the development team made a list of all the pages that would be needed for the site and a list of controls that could be used and re-used throughout the site. We will discuss the navigation control the team custom built for the site as well as several other web controls including combo boxes and the “datagridview”.

Navigation Control

Creating consistent, easily managed navigation for a web site is very important to the success of the web site. One of the best ways to ensure consistency and continuity is to create a custom navigation control that is implemented in all pages of the site. If every page implements the control, then if navigation changes, developers only need to change the code of the single control and deploy new versions rather than changing all pages in the site. The navigation control used here is a very simple control with only four options. Each of the options takes you to a different page. However, if I decide to add another page, I only need to add it to the custom navigation control we built. The following is the code for the custom control:
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="cntrlNavigation.ascx.cs" Inherits="cntrlNavigation" %>
 
<table style="text-align:center;">
<tr>
<td align="center" >
<asp:LinkButton ID="lnkMain" runat="server" Text="Main" onclick="lnk_Click" />&nbsp;&nbsp;&nbsp;
</td>
<td align="center" >
<asp:LinkButton ID="lnkMenu" runat="server" Text="Menu" onclick="lnk_Click" />&nbsp;&nbsp;&nbsp;
</td>
<td align="center" >
<asp:LinkButton ID="lnkCart" runat="server" Text="Cart" onclick="lnk_Click" />&nbsp;&nbsp;&nbsp;
</td>
<td align="center" >
<asp:LinkButton ID="lnkLogOut" runat="server" Text="Log Out" onclick="lnk_Click" />
</td>
</tr>
</table>
Notice that all the “LinkButtons” defined in the control have the same onclick event. We decided to redirect the user programmatically rather than creating hyperlinks for each linkbutton on the page. Now, let’s look at the “code-behind” for the control:
using System;
using System.Web.UI.WebControls;
 
namespace SSE698_Web_Development_Bridges_Gluvna
{
    public partial class cntrlNavigation : System.Web.UI.UserControl
    {
        protected void Page_Load(object sender, EventArgs e)
        {
        }
 
        protected void lnk_Click(object sender, EventArgs e)
        {
            switch (((LinkButton)sender).ID)
            {
                case "lnkMain":
                    Response.Redirect("Main.aspx");
                    break;
                case "lnkMenu":
                    Response.Redirect("Menu.aspx");
                    break;
                case "lnkCart":
                    Response.Redirect("Cart.aspx");
                    break;
                case "lnkLogOut":
                    Response.Redirect("Login.aspx");
                    break;
            }
        }
    }
}
In the lnk_click method, we have used a case statement to determine which page the user has reqested and the Response.Redirect method to actually send the user to the correct page.

In order to use the control in a page you must register the control at the top of the page so that it is accessible to the page on load. The following code is from the “Main” page of the site:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Main.aspx.cs" Inherits="Main" %>
 
<%@ Register src="cntrlNavigation.ascx" tagname="cntrlNavigation" tagprefix="uc1" %>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml" >
<link href="Styles.css" rel="stylesheet"  type="text/css" />
<head runat="server">
    <title>Home</title>
</head>
<body>
    <form id="form1" runat="server">
    <div class="center">
        <uc1:cntrlNavigation ID="cntrlNavigation1" runat="server" />
        <p>
            Welcome to the Brandy Britches Bakery, were customer service is our number one priority.
            All of our cakes are 100% hand made, never frozen and from all natural ingredients.
            Thank you for visiting our site, we hope you enjoy the visit.
        </p>
    </div>
    </form>
</body>
</html>

The result is this, and every other page in the site uses the navigation control will work the same way:

MainCss1.JPG

DataGridView

The GridView control was introduced by Microsoft with the .NET 2.0 framework as an enhancement to the DataGrid control. GridViews offer developers the ability to add paging, sorting, and selection with little or none of the extra coding that was previously required when using the DataGrid control. For our site, we use a GridView as a listing of the items on our “Menu”. It is a very simple example, but very effective. First we created a source of the data, programmatically for this example since we are only doing a static page at this stage of development. The following code illustrates how we created our data source:
private void loadDataSet()
{
   CCommon.ds.Menu.Clear();
   CCommon.ds.Menu.AddMenuRow(1, "Dark Chocalate Cake", "Desription of Dark Chocalate Cake", 25.00);
   CCommon.ds.Menu.AddMenuRow(2, "German Chocalate Cake", "Desription of German Chocalate Cake", 30.00);
   CCommon.ds.Menu.AddMenuRow(3, "Italian Wedding Cake", "Desription of Italian Wedding Cake", 250.00);
   CCommon.ds.Menu.AddMenuRow(4, "New York Cheese Cake", "Desription of New York Cheese Cake", 25.00);
   CCommon.ds.Menu.AddMenuRow(5, "Red Velvet Cake", "Description Red Velvet Cake", 35.00);
}
In this case we have a strongly typed dataset already defined in our classes with a table named menu, so all we are really doing is clearing out any data that might exist and repopulating with the data we want to show in the GridView control.
The GridView is defined in the actual web page like this:
<asp:gridview ID="gvMenu" runat="server" AutoGenerateColumns="False"
  AutoGenerateSelectButton="True" AllowPaging="True" SelectedIndex="1"
  OnSelectedIndexChanged="gvMenu_SelectedIndexChanged"
  DataKeyNames="ID" AlternatingRowStyle-BackColor="LightGray" >
  <Columns>
     <asp:BoundField DataField="ID" HeaderText="ID" Visible="true" InsertVisible="false" ReadOnly="True" SortExpression="ID" />
     <asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" />
     <asp:BoundField DataField="Description" HeaderText="Description" SortExpression="Description" />
     <asp:BoundField DataField="Cost" HeaderText="Price" SortExpression="Cost" />
  </Columns>
</asp:gridview>
Then in the "code behind" we want to bind our data source to the GridView:
private void loadMenu()
{
   gvMenu.DataSource = CCommon.ds.Menu;
   gvMenu.DataBind();
}
It's really quite simple and the result looks like this:

Menu.JPG

We want the menu to redirect to a different page with information about each item when the user clicks the select link, so we created an “on item clicked event”, which basically means that if one of the rows in the grid view is “clicked” at the select link, then a certain method is called. The following is our event handling method:
protected void gvMenu_SelectedIndexChanged(Object sender, EventArgs e)
{
    // Get the currently selected row
    GridViewRow row = gvMenu.SelectedRow;
    Response.Redirect(string.Format("MenuItem.aspx?ID={0}", row.Cells[1].Text));
}
For this example, let’s say that we want to see the Italian Wedding Cake, so we click select and we are redirected to a page that looks like this:
MenuItemWeddingCake.JPG

Collections

Collections in the .Net environment are very easy to use and manage. There are all types of collections from Generic to specialized and from typed to un-typed collection. The specific collection type we are going to be using today is the Hashtable. We will create the collection, populate the collection and read from the collection in our example. We will be using our collection as a container for where our images will be held.
The first thing that you need to know about collections within the .Net Framework is that they fall within one of the three name spaces listed below:
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
For the use of a HashTable, all that is needed is the namespace System.Collections.

Creating the Collection

The first thing that we are going to do is create the collection and we do that below:
private Hashtable _htImage = new Hashtable();
private Hashtable htImage
{
        get { return _htImage; }
        set { _htImage = value; }
}
 
Above you can see we create a Hashtable and instantiate the Hashtable with the keyword new. We named the table _htImage. We also create a property to use that will expose our Hashtable called htImage.

Populating the Collection

Populating a collection is as easy as using a .Add function and passing the expected parameters. Below we clear the Hashtable and then add five (key, value) pairs of data. The first integer value is the key, the second string value is the value.
htImage.Clear();
htImage.Add(1,  @"images\DarkChocolate.jpg");
htImage.Add(2,  @"images\GermanChocolate.jpg");
htImage.Add(3,  @"images\ItalianWedding.jpg");
htImage.Add(4,  @"images\NYStyleCheeseCake.jpg");
htImage.Add(5,  @"images\RedVelvet.jpg");

We do not do it in our example, but it is always best practice to use the .ContainsKey or .ContainsValue function to see if an item exist before adding it to the collection.

Reading a Collection

Reading a collection is very simple with the .Net Framework. To read the Hashtable all that a developer must do is [Hashtable object name][key value]. The Hashtable stores the key objects and value objects just as they were inserted. Below our example gets the key value from the query string. Take a look at the code.
imgItem.ImageUrl = htImage[int.Parse(Request.QueryString["ID"].ToString())].ToString();
In the example above you can see we read the htImage value and set it to the image URL of our image object.

Closing Thoughts on Collections

As you can see collections are very simple to use within the .Net Framework. All developers should make themselves aware of all the collection types and familiarize themselves with the most common collections. Collections are a powerful thing.